package com.phpxiu.app.kkylive;

import android.Manifest;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.Signature;
import android.content.res.AssetManager;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.os.Build;
import android.os.Environment;
import android.support.multidex.MultiDexApplication;
import android.support.v4.content.ContextCompat;
import android.util.Base64;
import android.util.DisplayMetrics;
import android.view.ViewGroup;
import android.widget.Toast;

import com.amap.api.location.AMapLocationClientOption;
import com.facebook.FacebookSdk;
import com.facebook.appevents.AppEventsLogger;
import com.facebook.drawee.backends.pipeline.Fresco;
import com.facebook.imagepipeline.core.ImagePipelineConfig;
import com.phpxiu.app.config.Constants;
import com.phpxiu.app.controller.avcontroller.QavsdkControl;
import com.phpxiu.app.kkylive.wxapi.WXEntryActivity;
import com.phpxiu.app.model.MySelfInfo;
import com.phpxiu.app.model.gift.Gift;
import com.phpxiu.app.model.list.LoveState;
import com.phpxiu.app.okhttp.OKHttp;
import com.phpxiu.app.push.PushUtil;
import com.phpxiu.app.utils.FileManager;
import com.phpxiu.app.utils.KKYUtil;
import com.phpxiu.app.utils.VoiceManager;
import com.phpxiu.app.view.BaseLogin;
import com.phpxiu.app.view.UserSetting;
import com.phpxiu.app.view.custom.PraiseImageView;
import com.phpxiu.app.view.custom.VerticalImageSpan;
import com.sina.weibo.sdk.api.share.IWeiboShareAPI;
import com.sina.weibo.sdk.api.share.WeiboShareSDK;
import com.tencent.TIMGroupReceiveMessageOpt;
import com.tencent.TIMLogLevel;
import com.tencent.TIMManager;
import com.tencent.TIMOfflinePushListener;
import com.tencent.TIMOfflinePushNotification;
import com.tencent.av.sdk.AVContext;
import com.tencent.mm.sdk.openapi.IWXAPI;
import com.tencent.mm.sdk.openapi.WXAPIFactory;
import com.tencent.qalsdk.sdk.MsfSdkUtils;
import com.tencent.tauth.Tencent;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;


/**
 * @file
 * @brief  酷酷鱼应用程序
 * @author 吴金洲
 * @note 酷酷鱼应用程序类，初始化全局变量。
 *
 */
public class KKYApp extends MultiDexApplication {
    public static final String TAG = "KKYApp";
    private static KKYApp app;
    public static float screenWidth=0;//屏幕宽px
    public static float screenHeight=0;//屏幕高px
    //声明AMapLocationClientOption对象
    public final static AMapLocationClientOption LP = new AMapLocationClientOption();
    public final static String KKY_LOG_DIR= Environment.getExternalStoragePublicDirectory("/").getPath()+"/com.phpxiu.log/";
    public final static String LOG_FILE_NAME="KuKuYu.txt";
    //新浪平台
    public static IWeiboShareAPI mSinaShareAPI = null;
    //QQ平台
    public static Tencent mQQ;
    //微信登录分享
    public static IWXAPI mWeiXinAPI;
    private SharedPreferences mSp;
    public  boolean isShowNotice=true;
    private static AssetManager assetManager;
    public final static Map<String,VerticalImageSpan>LV_SPAN_CACHE=new HashMap<String,VerticalImageSpan>();//等级图标ImageSpan缓存
    public final static Map<String,Bitmap>HEART_BITMAP_CACHE=new HashMap<String,Bitmap>();//七颜色心形图片缓存
    public final static List<PraiseImageView> HEART_ANIM_VIEWS_CACHE=new ArrayList<PraiseImageView>();//动画view缓存
    public final static Map<String,VerticalImageSpan>HEART_SPAN_CACHE=new HashMap<String,VerticalImageSpan>();//心形ImageSpan缓存
    public final static ViewGroup.LayoutParams HEART_VIEW_PARAM=new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
    public int HEART_SHAPE_SIZE;//心形动画图标大小
    public int HEART_SPAN_SIZE;
    public static final List<LoveState>STATES=new ArrayList<LoveState>();
    public List<Gift>GIFTS=new ArrayList<Gift>();//礼物列表
    public List<List<Gift>> GIFTS_PAGES=new ArrayList<List<Gift>>();//礼物分页列表
    /**
     * 获取实例
     * @return
     */
    public synchronized static KKYApp getInstance() {
        return app;
    }

    @Override
    public void onCreate() {
        try {
            super.onCreate();
            if(KKYUtil.DEBUG){
                showKeyHash();
            }
            screenWidth=getResources().getDisplayMetrics().widthPixels;
            screenHeight=getResources().getDisplayMetrics().heightPixels;
            LP.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);//高德高精度定位，GPS+网络定位功耗高
            LP.setOnceLocation(true);//单次定位
            LP.setNeedAddress(true);//定位返回地址信息
            FileManager.init(this);
            VoiceManager.getInstance().init(this);
            OKHttp.init(getApplicationContext());

            //Fresco图片加载库配置、初始化
            ImagePipelineConfig config = ImagePipelineConfig.newBuilder(getApplicationContext()).setDownsampleEnabled(true).build();
            Fresco.initialize(getApplicationContext(), config);
            //QQ分享登录实例创建
            if(mQQ==null){
                mQQ= Tencent.createInstance(BaseLogin.QQ_APP_ID, getApplicationContext());
            }
            //微信分享登录实例创建、注册
            if(mWeiXinAPI==null) {
                mWeiXinAPI = WXAPIFactory.createWXAPI(getApplicationContext(),BaseLogin.WX_APP_ID, true);
                mWeiXinAPI.registerApp(BaseLogin.WX_APP_ID);
            }
            //检测微信版本支持类型
            int wxSdkVersion = mWeiXinAPI.getWXAppSupportAPI();
            if (wxSdkVersion >= WXEntryActivity.TIMELINE_SUPPORTED_VERSION) {
                KKYUtil.log(TAG, "当前微信版本支持发送到朋友圈");
            } else {
                KKYUtil.log(TAG, "当前微信版本不支持发送到朋友圈");
            }
            // 创建微博分享接口实例
            mSinaShareAPI = WeiboShareSDK.createWeiboAPI(getApplicationContext(),BaseLogin.SINA_APP_KEY);
            mSinaShareAPI.registerApp();
            FacebookSdk.sdkInitialize(getApplicationContext());
            AppEventsLogger.activateApp(this);
            configLanguage();
            mSp=getSharedPreferences(Constants.USER_INFO, MODE_PRIVATE);
            isShowNotice=mSp.getBoolean(Constants.USER_NOTICE_SETTING, true);//获取通知开关状态
            KKYUtil.log("应用程序实例创建：" + (isShowNotice ? "接收显示通知" : "不接收显示通知"));
            PushUtil.getInstance().receivable(isShowNotice);
            assetManager=getAssets();
            initIMAVSDK();
            initHeartShape();
            initLoveStates(this);
            MySelfInfo.getInstance().getCache(getApplicationContext());//获取登录用户缓存信息
        }catch (Exception e){
            if(Build.VERSION.SDK_INT>=23) {
                if(checkMyPermission()){
                    saveStartErr(e);
                }
            }else{
                saveStartErr(e);
            }
        }
        app = this;
    }

    /**
     * 匹配语言
     */
    protected void configLanguage(){
        SharedPreferences sp=getSharedPreferences(UserSetting.KKY_USER_LANGUAGE_CONFIG,MODE_PRIVATE);
        int code=sp.getInt(UserSetting.KKY_CURRENT_LANGUAGE_CODE,0);
        Resources resources =getResources();//获得res资源对象
        Configuration config = resources.getConfiguration();//获得设置对象
        DisplayMetrics dm = resources.getDisplayMetrics();//获得屏幕参数：主要是分辨率，像素等。
        switch (code){
            case 1:
                config.locale = Locale.SIMPLIFIED_CHINESE; //简体中文
                break;
            case 2:
                config.locale = Locale.ENGLISH;
                break;
            default:
                config.locale= Locale.getDefault();
                break;
        }
        resources.updateConfiguration(config, dm);
    }

    /**
     * 初始化IM AV SDK实例
     */
    private void initIMAVSDK(){
        //初始化avsdk imsdk
        QavsdkControl.initQavsdk(this);
        //是否控制抬输出IM日志
        TIMManager.getInstance().setLogPrintEnable(false);
        //灯塔上报
        TIMManager.getInstance().disableBeaconReport();
        //IM AV SDK日志上报
        TIMManager.getInstance().setLogLevel(TIMLogLevel.OFF);
        //IM 实例初始化
        TIMManager.getInstance().init(this);
        //设调显示IM SDK版本号
        if(KKYUtil.DEBUG){
            String IMVersion= TIMManager.getInstance().getVersion();
            Toast.makeText(this, "IM版本号：" + IMVersion, Toast.LENGTH_LONG).show();
            KKYUtil.log("IM版本："+IMVersion);
        }
        if(KKYUtil.DEBUG){
            String AVVersion=AVContext.getVersion();
            Toast.makeText(this, "AVSDK版本号：" +AVVersion , Toast.LENGTH_LONG).show();
            KKYUtil.log("AVSDK版本号："+AVVersion);
        }
        //程序退出时会调用这里来显示IM推送通知，如果没有退出则不会调用
        if(MsfSdkUtils.isMainProcess(this)) {
            TIMManager.getInstance().setOfflinePushListener(new TIMOfflinePushListener() {
                @Override
                public void handleNotification(TIMOfflinePushNotification notification) {
                    if (notification.getGroupReceiveMsgOpt() == TIMGroupReceiveMessageOpt.ReceiveAndNotify){
                        //消息被设置为需要提醒
                        if(isShowNotice) {
                            PushUtil.getInstance().pushNotify(notification);
                        }
                    }
                }
            });
        }
    }

    /**
     * 初始化心形冒泡动画缓存值
     */
    private void initHeartShape(){
        HEART_SHAPE_SIZE=KKYUtil.dip2px(this,20);//心形图片大小
        HEART_SPAN_SIZE=KKYUtil.dip2px(this,15);
        HEART_VIEW_PARAM.width=HEART_SHAPE_SIZE;
        HEART_VIEW_PARAM.height=HEART_SHAPE_SIZE;
        try {
            String[] paths=assetManager.list("heartIcons");
            for (int i=0;i<paths.length;i++) {
                Bitmap bitmap=BitmapFactory.decodeStream(assetManager.open("heartIcons/" + paths[i]));
                Bitmap newBitMap=Bitmap.createScaledBitmap(bitmap,HEART_SHAPE_SIZE,HEART_SHAPE_SIZE,true);
                HEART_BITMAP_CACHE.put(paths[i].replace(".png",""),newBitMap);
                Bitmap span=Bitmap.createScaledBitmap(bitmap,HEART_SPAN_SIZE,HEART_SPAN_SIZE,true);
                HEART_SPAN_CACHE.put(paths[i].replace(".png",""),new VerticalImageSpan(this,span));
                newBitMap=null;
                if(bitmap!=newBitMap&&bitmap!=span) {
                    bitmap.recycle();
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 取得等级span,以高度的缩放比例等比缩放
     */
    public static VerticalImageSpan getLvSpan(int lv,float destWidth,float destHeight){
        if(app==null){
           return null;
        }
        //查找缓存
        VerticalImageSpan span=LV_SPAN_CACHE.get(""+lv);
        if(span!=null){
            return span;
        }
        try {
            Bitmap source= BitmapFactory.decodeStream(assetManager.open("lvIcons/"+lv+".png"));
            // 获得图片的宽高
            int width = source.getWidth();
            int height = source.getHeight();
            // 计算缩放比例
            float scaleHeight =destHeight/height;
            // 取得想要缩放的matrix参数
            Matrix matrix = new Matrix();
            matrix.postScale(scaleHeight,scaleHeight);
            // 得到新的图片
            Bitmap spanBitMap = Bitmap.createBitmap(source,0,0,width,height,matrix,true);
            span=new VerticalImageSpan(app.getApplicationContext(),spanBitMap);
            //newBitmap.recycle();//不能释放图片，ImageSpan绘制需要引用
            if(spanBitMap!=source) {
                source.recycle();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        if(span!=null){
           LV_SPAN_CACHE.put(""+lv,span);//缓存对象
        }
        return span;
    }


    /**
     * 初始化感情状态
     */
    public static void initLoveStates(Context context){
        STATES.clear();
        STATES.add(new LoveState("1",context.getString(R.string.edit_user_info_love_state_content_1)));
        STATES.add(new LoveState("2",context.getString(R.string.edit_user_info_love_state_content_2)));
        STATES.add(new LoveState("3",context.getString(R.string.edit_user_info_love_state_content_3)));
        STATES.add(new LoveState("4",context.getString(R.string.edit_user_info_love_state_content_4)));
        STATES.add(new LoveState("5",context.getString(R.string.edit_user_info_love_state_content_5)));
        STATES.add(new LoveState("6",context.getString(R.string.edit_user_info_love_state_content_6)));
    }

    public void setShowNotice(boolean isShowNotice) {
        this.isShowNotice = isShowNotice;
        KKYUtil.log("应用程序实例："+(isShowNotice?"接收显示通知":"不接收显示通知"));
        PushUtil.getInstance().receivable(isShowNotice);
    }

    final private void showKeyHash(){
        try {
            String packageName=getApplicationContext().getPackageName();
            PackageInfo info = getPackageManager().getPackageInfo(
                    packageName, PackageManager.GET_SIGNATURES);
            for (Signature signature : info.signatures) {
                MessageDigest md = MessageDigest.getInstance("SHA");
                md.update(signature.toByteArray());
                String key=Base64.encodeToString(md.digest(),Base64.DEFAULT);
                KKYUtil.log("Key Hash：" + key);
            }
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.getMessage();
        }
    }

    @Override
    public void onLowMemory() {
        super.onLowMemory();
        System.gc();
    }

    @Override
    public void onTrimMemory(int level) {
        // 程序在内存清理的时候执行
        super.onTrimMemory(level);
    }

    @Override
    public void onTerminate() {
        // 程序终止的时候执行
        super.onTerminate();
    }

    /**
     * 检测权限
     */
    private boolean checkMyPermission(){
        int permissionRead = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE);//读取存储卡
        if (permissionRead != PackageManager.PERMISSION_GRANTED) {//未授权读卡
            return false;
        }
        int permissionWrite = ContextCompat.checkSelfPermission(this,Manifest.permission.WRITE_EXTERNAL_STORAGE);//写存储卡
        if (permissionWrite != PackageManager.PERMISSION_GRANTED) {//未授权写卡
            return false;
        }
        return true;
    }


    /**
     * 保存启动异常
     * @param ex
     */
    private void saveStartErr(Exception ex){
        StringBuffer startLogErr=new StringBuffer("启动异常：");
        startLogErr.append(getTrace(ex));
        try{
            File file = new File(KKY_LOG_DIR);
            if(!file.exists()){
                file.mkdirs();
            }
            File logFile = new File(KKY_LOG_DIR,LOG_FILE_NAME);
            try {
                if(!logFile.exists()){
                    logFile.createNewFile();
                }else{
                    if(!logFile.isFile()){
                        logFile.delete();
                        logFile.createNewFile();
                    }
                }
                FileWriter filerWriter = new FileWriter(logFile, true);//后面这个参数代表是不是要接上文件中原来的数据，不进行覆盖
                BufferedWriter bufWriter = new BufferedWriter(filerWriter);
                bufWriter.write(startLogErr.toString());
                bufWriter.newLine();
                bufWriter.close();
                filerWriter.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }catch(Exception e){
            e.printStackTrace();
        }
    }

    /**
     * 获取异常信息
     * @param ex
     * @return
     */
    public static String getTrace(Throwable ex){
        StringBuffer err=new StringBuffer();
        String msg = ex.getLocalizedMessage();
        ex.printStackTrace();
        String name = ex.getClass().getName();
        if (msg == null) {
            return name;
        }
        err.append(name + ": " + msg) ;
        StackTraceElement[] stack = ex.getStackTrace();
        if (stack != null) {
            for (int i = 0; i < stack.length; i++) {
                err.append("Exception:");
                err.append("\tat ");
                err.append(stack[i].toString());
                err.append("\n");
            }
        }

        Throwable cause = ex.getCause();
        if (cause != null) {
            err.append("Caused by: ");
            stack =ex.getCause().getStackTrace();
            if (stack != null) {
                for (int i = 0; i < stack.length; i++) {
                    err.append("Exception:");
                    err.append("\tat ");
                    err.append(stack[i].toString());
                    err.append("\n");
                }
            }
        }
        return err.toString();
    }

}
